package com.utils.worldcup;

import com.google.common.collect.Lists;
import com.utils.bfs.Graph;

import java.util.*;

public class WorldCupOneUtils {

    public static String[] eventA = new String[]{"主场VS客场"};

    private static class SingletonHolder {
        private static final WorldCupOneUtils INSTANCE = new WorldCupOneUtils();

    }

    private WorldCupOneUtils() {

    }

    public static WorldCupOneUtils getInstance() {
        return WorldCupOneUtils.SingletonHolder.INSTANCE;
    }


    public Map<String, Object> getOrder(int win, int lost, int pp, double[] scoreA, double[] scoreB, String[] scoreBStr) {
        Map<String, Object> resultMap = new HashMap<>();
        Map<String, String> totalScore = new HashMap<>();
        LinkedList<String[]> list = new LinkedList<>();
        Map<String, String> map = new HashMap<>();
        List<String> allLine = new ArrayList<>();
        //初始化根节点
        Graph theGraph = new Graph();
        String[] opArr = new String[]{"#"};
        list.add(opArr);
        //初始化事件分支
        for (String label : eventA) {
            cg(label, map, list);
        }
        //根节点以及中间节点
        for (int i = 0; i < list.size(); i++) {
            if (i + 1 == list.size()) {
                break;
            }
            String[] a1 = list.get(i);
            String[] a2 = list.get(i + 1);
            addEdge(theGraph, a1, a2);
        }
        String[] last = list.getLast();
        //叶子节点
        for (String aLast : last) {
            theGraph.addVertex(aLast);
        }

        StringBuilder sb = new StringBuilder();
        List<List<String>> allPathList = theGraph.mst();
        int total = 0;
        for (List<String> onePath : allPathList) {
            if (sb.length() > 0) {
                sb.delete(0, sb.length());
            }
            for (String node : onePath) {
                sb.append(node).append(",");
            }
            String options = sb.substring(2, sb.length() - 1);
            allLine.add(options);
            total += 1;
        }
        for (String line : allLine) {
            String[] all = line.split(",");
            for (String cg : all) {
                String end = map.get(cg);
                String vStr = totalScore.get(line);
                double v;
                if (null == vStr) {
                    v = 0.0;
                } else {
                    v = Double.parseDouble(vStr);
                }
                if (end.endsWith("平")) {
                    v += scoreB[0] * pp;
                } else if (end.endsWith("主胜")) {
                    v += scoreA[0] * win;
                } else if (end.endsWith("客胜")) {
                    v += scoreA[1] * lost;
                }
                totalScore.put(line, String.format("%.2f", v));
            }

        }
        StringBuilder result = new StringBuilder();
        for (String e : eventA) {
            double a = getV(e + "主胜", scoreA);
            double c = getV(e + "客胜", scoreA);
            result.append(e).append("[选2个赔率:").append(a).append("/").append(c).append("]\n");
        }
        result.append("\n下注方案:\n");
        result.append(scoreA[0]).append("的下注").append(win).append("元\n");
        result.append(scoreA[1]).append("的下注").append(lost).append("元\n");
        result.append(scoreBStr[0]).append("~").append(scoreBStr[scoreB.length - 1]).append("比分各下注").append(pp).append("元，共").append(scoreB.length * pp).append("元\n");
        result.append("总成本：").append(win + lost + pp * scoreB.length).append("元\n");
        result.append("\n结局共").append(total).append("个情况如下：\n");
        totalScore.put("D", "看备注，未知 ?? ");
        totalScore.forEach((k, v) -> {
            result.append(k).append(" = ").append(v).append("元\n");
            if ("W".equals(k)) {
                resultMap.put("wCost", Double.parseDouble(v));
            } else if ("L".equals(k)) {
                resultMap.put("lCost", Double.parseDouble(v));
            }
        });
        result.append("\n备注：\n");
        map.forEach((k, v) -> {
            switch (k) {
                case "W":
                    result.append(k).append(" 代表 ").append(scoreA[0]).append("的下注").append("\n");
                    break;
                case "L":
                    result.append(k).append(" 代表 ").append(scoreA[1]).append("的下注").append("\n");
                    break;
                case "D":
                    result.append(k).append(" 代表 ").append("比分的下注").append("\n");
                    break;
            }
        });
        result.append("下注以下比分获奖分别是：\n");
        double min = scoreB[0] * pp;
        for (int i = 0; i < scoreB.length; i++) {
            double v = scoreB[i] * pp;
            if (v < min) {
                min = v;
            }
            result.append(scoreBStr[i]).append(" 可获得 ").append(String.format("%.2f", v)).append("元\n");
        }

        resultMap.put("result", result.toString());
        resultMap.put("cost", win + lost + pp * scoreB.length);
        resultMap.put("dCost", min);
        return resultMap;
    }


    private static double getV(String end, double[] scoreA) {
        double v = 0.0;
        if (end.endsWith("主胜")) {
            v = scoreA[0];
        } else if (end.endsWith("客胜")) {
            v = scoreA[1];
        }
        return v;
    }


    /**
     * 添加子节点
     */
    private static void addEdge(Graph theGraph, String[] a1, String[] a2) {
        for (String root : a1) {
            //添加叶子根
            theGraph.addVertex(root);
            //再给叶子根添加子节点
            for (String anA2 : a2) {
                theGraph.addEdge(root, anA2);
            }

        }
    }

    /**
     * 分支事件
     */
    private static void cg(String label, Map<String, String> map, LinkedList<String[]> list) {
        String g1 = "W";
        String g2 = "D";
        String g3 = "L";
        map.put(g1, label + " 主胜");
        map.put(g2, label + " 平");
        map.put(g3, label + " 客胜");
        String[] opArr;
        List<String> opCount = Lists.newArrayList(g1, g2, g3);
        opArr = new String[opCount.size()];
        opArr = opCount.toArray(opArr);
        list.add(opArr);
    }

}
